package com.ruoyi.eqmonitor.dispose.task;

import com.alibaba.fastjson2.JSONArray;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.eqmonitor.dispose.service.IExteriorMonitorDataService;
import com.ruoyi.eqmonitor.domain.OptDevice;
import com.ruoyi.eqmonitor.domain.OptDeviceAlarm;
import com.ruoyi.eqmonitor.domain.OptDeviceAlarmDayData;
import com.ruoyi.eqmonitor.domain.OptDeviceMonitorConfig;
import com.ruoyi.eqmonitor.dtos.OptDeviceHistoryDto;
import com.ruoyi.eqmonitor.service.*;
import com.ruoyi.eqmonitor.utils.Constant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 跳变报警
 */
@Slf4j
@Component
public class JumpChangeTask {

    @Resource
    private IOptDeviceService optDeviceService;

    @Resource
    private IExteriorMonitorDataService monitorDataService;
    @Resource
    private IOptDeviceAlarmService deviceAlarmService;
    @Resource
    private IOptDeviceMonitorDataService optDeviceMonitorDataService;
    @Resource
    private IOptDeviceAlarmDayDataService optDeviceAlarmDayDataService;
    /**
     * 每天执行一次 判断设备跳变次数
     */
    //@Scheduled(cron = "0 0 1 * * ?")
    /*public void validateDeviceJumpChange() {
        //排水液位设备list
        List<OptDevice> deviceList = optDeviceService.listByDeviceType(Constant.EquipmentType.SY800_L_Y0.getCode());
        LocalDateTime start = LocalDateTime.of(LocalDate.now().minusDays(1), LocalTime.MIN);
        LocalDateTime end = LocalDateTime.of(LocalDate.now().minusDays(1), LocalTime.MAX);
        deviceList.forEach(optDevice -> {
            String snCode = optDevice.getDeviceCode();
            double maxData = monitorDataService.getMaxValueBySnCodeAndTime(start, end, snCode);
            double halfData = maxData/2d;
            long alarmCount = monitorDataService.countBySncodeAndTimeAndHalfData(snCode, start, end, halfData);
            if(alarmCount > 0){
                OptDeviceAlarm newAlarm = new OptDeviceAlarm();
                newAlarm.setDeviceName(optDevice.getDeviceName());
                newAlarm.setDeviceCode(optDevice.getDeviceCode());
                newAlarm.setSiteName(optDevice.getSiteName());
                newAlarm.setDeviceType(optDevice.getDeviceType());
                newAlarm.setInstallTime(optDevice.getInstallTime());
                newAlarm.setAbx(optDevice.getAbx());
                newAlarm.setAby(optDevice.getAby());
                newAlarm.setAlarmCode("0x05D1");
                // 跳变报警
                newAlarm.setAlarmType(Constant.AlarmType.JUMP_CHANGE.getValue());
                newAlarm.setAlarmCount((int) alarmCount);
                newAlarm.setAlarmPhenomenon("13");
                newAlarm.setConfirmAlarm(Constant.ConfirmAlarmType.UNCONFIRMED.getValue());
                newAlarm.setAlarmCode(StringUtils.EMPTY);
                newAlarm.setPersistentStatus(Constant.TRUE);
                newAlarm.setAlarmTime(new Date());
                newAlarm.setLastAlarmTime(new Date());
                newAlarm.setLastAlarmTime(new Date());
                deviceAlarmService.save(newAlarm);
            }
        });
    }*/
    @Resource
    private IOptDeviceMonitorConfigService optDeviceMonitorConfigService;
    //跳变报警先注释掉了
    //@Scheduled(cron = "0 0 0 * * ?")
    public void validateNew(){
        ZoneId zoneId = ZoneId.systemDefault();
        //排水液位设备list
        List<OptDevice> deviceList = optDeviceService.listByDeviceType(Constant.EquipmentType.SY800_L_Y0.getCode());
        OptDeviceHistoryDto historyDto1 = new OptDeviceHistoryDto();
        LocalDateTime start = LocalDateTime.of(LocalDate.now().minusDays(1), LocalTime.MIN);
        ZonedDateTime zdt1 = start.atZone(zoneId);
        LocalDateTime end = LocalDateTime.of(LocalDate.now().minusDays(1), LocalTime.MAX);
        ZonedDateTime zdt2 = end.atZone(zoneId);
        historyDto1.setAggregator("avg");
        historyDto1.setDownsample("1h");
        historyDto1.setStartTime(Date.from(zdt1.toInstant()));
        historyDto1.setEndTime(Date.from(zdt2.toInstant()));
        historyDto1.setMonitorCode("0x05D1");
        historyDto1.setDeviceCodes(deviceList.stream().map(OptDevice::getDeviceCode).collect(Collectors.toList()));
        Map<String, List<Map<String, Object>>> data1 = optDeviceMonitorDataService.getDownsampleHistory(historyDto1);

         start = LocalDateTime.of(LocalDate.now().minusDays(2), LocalTime.MIN);
         end = LocalDateTime.of(LocalDate.now().minusDays(2), LocalTime.MAX);
         zdt1 = start.atZone(zoneId);
         zdt2 = end.atZone(zoneId);
        historyDto1.setStartTime(Date.from(zdt1.toInstant()));
        historyDto1.setEndTime(Date.from(zdt2.toInstant()));
        Map<String, List<Map<String, Object>>> data2 = optDeviceMonitorDataService.getDownsampleHistory(historyDto1);

        deviceList.forEach(optDevice -> {
            int alarmCount = 0;
            List<Map<String, Object>> list1 = data1.get(optDevice.getDeviceCode());
            List<Map<String, Object>> list2 = data2.get(optDevice.getDeviceCode());
            for (String time:
                 getTimeList()) {
                double d1 = 0d;
                if(list1!=null&&list1.size()!=0){
                    Map<String, Object> map = list1.stream().filter(m->time.equals(m.get("time"))).findFirst().get();
                    d1 = Double.parseDouble(map.get("value").toString());
                }
                double d2 = 0d;
                if(list2!=null&&list2.size()!=0){
                    Map<String, Object> map = list2.stream().filter(m->time.equals(m.get("time"))).findFirst().get();
                    d2 = Double.parseDouble(map.get("value").toString());
                }
                if(d1!=0 && d2!=0){
                    if(d1/d2 >2 || d1/d2 <0.5){
                        alarmCount++;
                    }
                }
            }
            if(alarmCount > 0){
                OptDeviceAlarm newAlarm = new OptDeviceAlarm();
                newAlarm.setDeviceName(optDevice.getDeviceName());
                newAlarm.setDeviceCode(optDevice.getDeviceCode());
                newAlarm.setSiteName(optDevice.getSiteName());
                newAlarm.setDeviceType(optDevice.getDeviceType());
                newAlarm.setInstallTime(optDevice.getInstallTime());
                newAlarm.setAbx(optDevice.getAbx());
                newAlarm.setAby(optDevice.getAby());
                newAlarm.setAlarmCode("0x05D1");
                // 跳变报警
                newAlarm.setAlarmType(Constant.AlarmType.JUMP_CHANGE.getValue());
                newAlarm.setAlarmCount(alarmCount);
                newAlarm.setAlarmPhenomenon("13");
                newAlarm.setConfirmAlarm(Constant.ConfirmAlarmType.UNCONFIRMED.getValue());
                newAlarm.setPersistentStatus(Constant.TRUE);
                newAlarm.setAlarmTime(new Date());
                newAlarm.setLastAlarmTime(new Date());
                newAlarm.setLastAlarmTime(new Date());
                OptDeviceMonitorConfig config = optDeviceMonitorConfigService.getByDeviceCode(optDevice.getDeviceCode(), "0x05D1");
                if(config!=null){
                    newAlarm.setConfigAlarmValue(config.getAlarmValue());
                    newAlarm.setConfigUpperLimit(config.getUpperLimit());
                }
                deviceAlarmService.save(newAlarm);

                OptDeviceAlarmDayData optDeviceAlarmDayData = new OptDeviceAlarmDayData();
                optDeviceAlarmDayData.setAlarmId(newAlarm.getId());
                optDeviceAlarmDayData.setDay1(JSONArray.toJSONString(list1.stream().map(d->Double.parseDouble(d.get("value").toString())).collect(Collectors.toList())));
                optDeviceAlarmDayData.setDay2(JSONArray.toJSONString(list2.stream().map(d->Double.parseDouble(d.get("value").toString())).collect(Collectors.toList())));
                optDeviceAlarmDayDataService.save(optDeviceAlarmDayData);
            }
        });
    }
    public List<String> getTimeList(){
        List<String> list = new ArrayList<>();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm");
        IntStream.range(0,24).forEach(i->{
            list.add(df.format(LocalTime.of(i, 0)));
        });
        return list;
    }
    public static void main(String[] args) {
        double d1 = 15;
        double d2 = 20;
        System.out.println(d1/d2);
    }
}
